From 4a9fa1e7505651c3074b1a620047f6bfc5158a5a Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Sat, 13 Feb 2016 02:31:47 +0100 Subject: [PATCH] css: Add API to handle order when printing calc() Also, add some tests and update old ones to print calc() statements correctly. --- gtk/gtkcsscalcvalue.c | 20 +++++++++++++++++++- gtk/gtkcssdimensionvalue.c | 30 +++++++++++++++++++++++++++++- gtk/gtkcssnumbervalue.c | 21 +++++++++++++++++++++ gtk/gtkcssnumbervalueprivate.h | 2 ++ testsuite/css/parser/Makefile.am | 1 + testsuite/css/parser/calc.css | 14 +++++++++++++- testsuite/css/parser/calc.ref.css | 19 +++++++++++++++++++ 7 files changed, 104 insertions(+), 3 deletions(-) create mode 100644 testsuite/css/parser/calc.ref.css diff --git a/gtk/gtkcsscalcvalue.c b/gtk/gtkcsscalcvalue.c index 374b23313b..8df2a67ad9 100644 --- a/gtk/gtkcsscalcvalue.c +++ b/gtk/gtkcsscalcvalue.c @@ -73,6 +73,9 @@ static void gtk_css_calc_array_add (GPtrArray *array, GtkCssValue *value) { gsize i; + gint calc_term_order; + + calc_term_order = gtk_css_number_value_get_calc_term_order (value); for (i = 0; i < array->len; i++) { @@ -84,6 +87,11 @@ gtk_css_calc_array_add (GPtrArray *array, GtkCssValue *value) _gtk_css_value_unref (value); return; } + else if (gtk_css_number_value_get_calc_term_order (g_ptr_array_index (array, i)) > calc_term_order) + { + g_ptr_array_insert (array, i, value); + return; + } } g_ptr_array_add (array, value); @@ -235,6 +243,15 @@ gtk_css_value_calc_try_add (const GtkCssValue *value1, return NULL; } +static gint +gtk_css_value_calc_get_calc_term_order (const GtkCssValue *value) +{ + /* This should never be needed because calc() can't contain calc(), + * but eh... + */ + return 0; +} + static const GtkCssNumberValueClass GTK_CSS_VALUE_CALC = { { gtk_css_value_calc_free, @@ -247,7 +264,8 @@ static const GtkCssNumberValueClass GTK_CSS_VALUE_CALC = { gtk_css_value_calc_get_dimension, gtk_css_value_calc_has_percent, gtk_css_value_calc_multiply, - gtk_css_value_calc_try_add + gtk_css_value_calc_try_add, + gtk_css_value_calc_get_calc_term_order }; static GtkCssValue * diff --git a/gtk/gtkcssdimensionvalue.c b/gtk/gtkcssdimensionvalue.c index f1a4d90bfb..87efb7a6d6 100644 --- a/gtk/gtkcssdimensionvalue.c +++ b/gtk/gtkcssdimensionvalue.c @@ -258,6 +258,33 @@ gtk_css_value_dimension_try_add (const GtkCssValue *value1, return gtk_css_dimension_value_new (value1->value + value2->value, value1->unit); } +static gint +gtk_css_value_dimension_get_calc_term_order (const GtkCssValue *value) +{ + /* note: the order is alphabetic */ + guint order_per_unit[] = { + /* [GTK_CSS_NUMBER] = */ 0, + /* [GTK_CSS_PERCENT] = */ 16, + /* [GTK_CSS_PX] = */ 11, + /* [GTK_CSS_PT] = */ 10, + /* [GTK_CSS_EM] = */ 3, + /* [GTK_CSS_EX] = */ 4, + /* [GTK_CSS_REM] = */ 13, + /* [GTK_CSS_PC] = */ 9, + /* [GTK_CSS_IN] = */ 6, + /* [GTK_CSS_CM] = */ 1, + /* [GTK_CSS_MM] = */ 7, + /* [GTK_CSS_RAD] = */ 12, + /* [GTK_CSS_DEG] = */ 2, + /* [GTK_CSS_GRAD] = */ 5, + /* [GTK_CSS_TURN] = */ 15, + /* [GTK_CSS_S] = */ 14, + /* [GTK_CSS_MS] = */ 8 + }; + + return 1000 + order_per_unit[value->unit]; +} + static const GtkCssNumberValueClass GTK_CSS_VALUE_DIMENSION = { { gtk_css_value_dimension_free, @@ -270,7 +297,8 @@ static const GtkCssNumberValueClass GTK_CSS_VALUE_DIMENSION = { gtk_css_value_dimension_get_dimension, gtk_css_value_dimension_has_percent, gtk_css_value_dimension_multiply, - gtk_css_value_dimension_try_add + gtk_css_value_dimension_try_add, + gtk_css_value_dimension_get_calc_term_order }; GtkCssValue * diff --git a/gtk/gtkcssnumbervalue.c b/gtk/gtkcssnumbervalue.c index b7892c7603..d685fda902 100644 --- a/gtk/gtkcssnumbervalue.c +++ b/gtk/gtkcssnumbervalue.c @@ -78,6 +78,27 @@ gtk_css_number_value_try_add (const GtkCssValue *value1, return number_value_class->try_add (value1, value2); } +/* + * gtk_css_number_value_get_calc_term_order: + * @value: Value to compute order for + * + * Determines the position of @value when printed as part of a calc() + * expression. Values with lower numbers are printed first. Note that + * these numbers are arbitrary, so when adding new types of values to + * print, feel free to change them in implementations so that they + * match. + * + * Returns: Magic value determining placement when printing calc() + * expression. + */ +gint +gtk_css_number_value_get_calc_term_order (const GtkCssValue *value) +{ + GtkCssNumberValueClass *number_value_class = (GtkCssNumberValueClass *) value->class; + + return number_value_class->get_calc_term_order (value); +} + GtkCssValue * _gtk_css_number_value_new (double value, GtkCssUnit unit) diff --git a/gtk/gtkcssnumbervalueprivate.h b/gtk/gtkcssnumbervalueprivate.h index 8e77aaa9f0..7cb750f87c 100644 --- a/gtk/gtkcssnumbervalueprivate.h +++ b/gtk/gtkcssnumbervalueprivate.h @@ -49,6 +49,7 @@ struct _GtkCssNumberValueClass { double factor); GtkCssValue * (* try_add) (const GtkCssValue *value1, const GtkCssValue *value2); + gint (* get_calc_term_order) (const GtkCssValue *value); }; GtkCssValue * _gtk_css_number_value_new (double value, @@ -65,6 +66,7 @@ GtkCssValue * gtk_css_number_value_add (GtkCssValue *val GtkCssValue *value2); GtkCssValue * gtk_css_number_value_try_add (const GtkCssValue *value1, const GtkCssValue *value2); +gint gtk_css_number_value_get_calc_term_order (const GtkCssValue *value); double _gtk_css_number_value_get (const GtkCssValue *number, double one_hundred_percent); diff --git a/testsuite/css/parser/Makefile.am b/testsuite/css/parser/Makefile.am index 0cc0cce1b8..fcef07213a 100644 --- a/testsuite/css/parser/Makefile.am +++ b/testsuite/css/parser/Makefile.am @@ -227,6 +227,7 @@ test_data = \ box-shadow.css \ box-shadow.ref.css \ calc.css \ + calc.ref.css \ calc-simple.css \ calc-simple.ref.css \ close-at-end-of-file.css \ diff --git a/testsuite/css/parser/calc.css b/testsuite/css/parser/calc.css index 2c22095c7c..6e7bf54700 100644 --- a/testsuite/css/parser/calc.css +++ b/testsuite/css/parser/calc.css @@ -2,6 +2,18 @@ a { margin-left: calc(3px + 1em); } -a { +b { transition-duration: calc(1s - 100ms + -100ms); } + +c { + margin-left: calc(-2px + 1em + 4px); +} + +d { + background-size: calc( 100% - 10px ); +} + +e { + border-left-width: calc(1px + 1px); +} diff --git a/testsuite/css/parser/calc.ref.css b/testsuite/css/parser/calc.ref.css new file mode 100644 index 0000000000..4e858f70c8 --- /dev/null +++ b/testsuite/css/parser/calc.ref.css @@ -0,0 +1,19 @@ +a { + margin-left: calc(1em + 3px); +} + +b { + transition-duration: calc(-200ms + 1s); +} + +c { + margin-left: calc(1em + 2px); +} + +d { + background-size: calc(-10px + 100%); +} + +e { + border-left-width: 2px; +} -- 2.30.2